package cn.thoughtworks.school.utils;


import cn.thoughtworks.school.requestParams.YmlConvertQuiz;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
import org.yaml.snakeyaml.Yaml;

import java.io.*;
import java.util.Enumeration;
import java.util.Map;

public class ZipUtil {

  private static final String CHINESE_CHARSET = "GBK";

  private static final int CACHE_SIZE = 1024;


  public static void zip(String sourceFolder, String zipFilePath) throws Exception {
    OutputStream out = new FileOutputStream(zipFilePath);
    BufferedOutputStream bos = new BufferedOutputStream(out);
    ZipOutputStream zos = new ZipOutputStream(bos);
    zos.setEncoding(CHINESE_CHARSET);
    File file = new File(sourceFolder);
    String basePath;
    if (file.isDirectory()) {
      basePath = file.getPath();
    } else {
      basePath = file.getParent();
    }
    zipFile(file, basePath, zos);
    zos.closeEntry();
    zos.close();
    bos.close();
    out.close();
  }

  private static void zipFile(File parentFile, String basePath, ZipOutputStream zos) throws Exception {
    File[] files;
    if (parentFile.isDirectory()) {
      files = parentFile.listFiles();
    } else {
      files = new File[1];
      files[0] = parentFile;
    }
    String pathName;
    InputStream is;
    BufferedInputStream bis;
    byte[] cache = new byte[CACHE_SIZE];
    for (File file : files) {
      if (file.isDirectory()) {
        basePath = basePath.replace('\\', '/');
        if (basePath.substring(basePath.length() - 1).equals("/")) {
          pathName = file.getPath().substring(basePath.length()) + "/";
        } else {
          pathName = file.getPath().substring(basePath.length() + 1) + "/";
        }

        zos.putNextEntry(new ZipEntry(pathName));
        zipFile(file, basePath, zos);
      } else {
        pathName = file.getPath().substring(basePath.length());
        pathName = pathName.replace('\\', '/');
        if (pathName.substring(0, 1).equals("/")) {
          pathName = pathName.substring(1);
        }
        is = new FileInputStream(file);
        bis = new BufferedInputStream(is);
        zos.putNextEntry(new ZipEntry(pathName));
        int nRead = 0;
        while ((nRead = bis.read(cache, 0, CACHE_SIZE)) != -1) {
          zos.write(cache, 0, nRead);
        }
        bis.close();
        is.close();
      }
    }
  }

  public static YmlConvertQuiz readYml(File file) throws IOException {
    YmlConvertQuiz quizConverter = new YmlConvertQuiz();

    ZipFile zipFile = new ZipFile(file);
    Enumeration<?> enumeration = zipFile.getEntries();
    Yaml yaml = new Yaml();
    ZipEntry zipEntry;
    while (enumeration.hasMoreElements()) {
      zipEntry = (ZipEntry) enumeration.nextElement();
      String fileName = zipEntry.getName();
      if (fileName.contains("__MACOSX")) {
        continue;
      }
      if (fileName.endsWith(".yml") || fileName.endsWith(".yaml")) {
        InputStream in = zipFile.getInputStream(zipEntry);
        Map quiz = yaml.load(in);
        quizConverter.add(quiz, fileName);
        in.close();
      }

    }
    return quizConverter;
  }
}
